package com.aplikata.evok.ui;

import java.io.Serializable;
import java.math.BigInteger;
import java.util.Date;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;

import org.primefaces.event.DateSelectEvent;
import org.primefaces.event.ScheduleEntryMoveEvent;
import org.primefaces.event.ScheduleEntryResizeEvent;
import org.primefaces.event.ScheduleEntrySelectEvent;
import org.primefaces.model.DefaultScheduleEvent;
import org.primefaces.model.LazyScheduleModel;
import org.primefaces.model.ScheduleEvent;
import org.primefaces.model.ScheduleModel;

import com.aplikata.bo.Node;
import com.aplikata.bo.UserEvent;
import com.aplikata.constants.Constants;
import com.aplikata.evok.bo.DoctorSchedule;
import com.aplikata.evok.bo.Patient;
import com.aplikata.evok.constants.EvokConstants;
import com.aplikata.evok.service.EvokPatientService;
import com.aplikata.ui.UIBean;
import com.aplikata.util.FacesUtil;

/**
 * @ClassName: EvokDoctorScheduleBean
 * @Description: TODO
 * @author Huyun
 * @date Sep 6, 2012 12:47:03 PM
 */
@ManagedBean(name = "patientScheduleBean")
@ViewScoped
public class EvokPatientScheduleBean extends UIBean {

	private static final long serialVersionUID = 1L;

	@ManagedProperty(value = "#{evokPatientService}")
	private EvokPatientService patientService;
	private ScheduleModel lazyEventModel;
	private ScheduleEvent sEvent = new DefaultScheduleEvent();
	private UserEvent uEvent;
	private int eventAmount;
	private List<Object[]> todoList;

	private String header;
	private DoctorSchedule doctorSchedule;

	private Integer calendarType;
	private Object[] therapyObj;

	@PostConstruct
	public void init() {
		doctorSchedule = new DoctorSchedule();
		if(calendarType == null){
			calendarType = EvokConstants.CALENDAR_TYPE_OTHER;
		}
	}

	public ScheduleModel getLazyEventModel() {
		if (lazyEventModel == null) {
			lazyEventModel = new LazyScheduleModel() {

				private static final long serialVersionUID = 1L;

				@Override
				public void loadEvents(Date start, Date end) {
					clear();
					List<ScheduleEvent> list = patientService.findPatientAllCalendar(getSessionUser().getId(), start, end);

					if (list == null || list.isEmpty())
						return;

					for (ScheduleEvent event : list) {
						this.addEvent(event);
					}
				}
			};
		}
		return lazyEventModel;
	}

	public void onDateSelect(DateSelectEvent selectEvent) {
		sEvent = new DefaultScheduleEvent("", selectEvent.getDate(), selectEvent.getDate());
		calendarType = EvokConstants.CALENDAR_TYPE_OTHER;
		doctorSchedule = new DoctorSchedule(EvokConstants.DOC_RESERVATION_STATUS_NORMAL);
		therapyObj = null;
	}

	public void onEventSelect(ScheduleEntrySelectEvent selectEvent) {
		sEvent = selectEvent.getScheduleEvent();
		Object obj = sEvent.getData();

		if (obj instanceof UserEvent) {
			calendarType = EvokConstants.CALENDAR_TYPE_OTHER;
			uEvent = (UserEvent) obj;
		} else if (obj instanceof DoctorSchedule) {
			calendarType = EvokConstants.CALENDAR_TYPE_PATIENT;
			doctorSchedule = (DoctorSchedule) obj;
			if (doctorSchedule.getPatientTherapy() == null) {
				therapyObj = null;
			} else {
				therapyObj = patientService.getTherapyObjForCalendar(doctorSchedule.getPatientTherapy().getId());
			}
		}
	}

	public void submitEventAction() {
		try {
			if (sEvent.getId() == null) {
				uEvent = new UserEvent(this.getSessionUser());
			}else{
				uEvent = (UserEvent) sEvent.getData();
			}

			uEvent.setTimeFrom(sEvent.getStartDate());
			uEvent.setTimeTo(sEvent.getEndDate());
			uEvent.setTitle(sEvent.getTitle());
			uEvent = (UserEvent) patientService.merge(uEvent);

			lazyEventModel = null;
			lazyEventModel = this.getLazyEventModel();
			sEvent = new DefaultScheduleEvent();
			todoList = null;
			todoList = this.getTodoList();
		} catch (Exception e) {
			FacesUtil.addActionListenerException(e, log);
		}
	}

	public String goTherapyAction() {
		FacesContext.getCurrentInstance().getExternalContext().getFlash()
				.put(EvokConstants.FLASH_PATIENT_THERAPY, doctorSchedule.getPatientTherapy());

		Node node = (Node) patientService.findSingleByProperty(Node.class, Node.DESCRIPTION,
				EvokConstants.PAGE_PATIENT_THERAPY_HISTORY);
		FacesUtil.setManagedBeanInSession(Constants.SESSION_SELECTED_MENU, node);
		return EvokConstants.PAGE_PATIENT_THERAPY_HISTORY;
	}

	public void deleteEvent() {
		try {
			if (sEvent.getData() != null) {
				Object obj = sEvent.getData();
				patientService.delete((Serializable) obj);
				lazyEventModel = null;
				lazyEventModel = this.getLazyEventModel();
				todoList = null;
				todoList = this.getTodoList();
				sEvent = new DefaultScheduleEvent();
			}
		} catch (Exception e) {
			FacesUtil.addActionListenerException(e, log);
		}
	}

	public void onEventMove(ScheduleEntryMoveEvent event) {
		try {
			uEvent = (UserEvent) event.getScheduleEvent().getData();
			patientService.merge(uEvent);
			lazyEventModel = null;
			lazyEventModel = this.getLazyEventModel();
		} catch (Exception e) {
			FacesUtil.addActionListenerException(e, log);
		}
	}

	public void onEventResize(ScheduleEntryResizeEvent event) {
		try {
			uEvent = (UserEvent) event.getScheduleEvent().getData();
			patientService.merge(uEvent);
			lazyEventModel = null;
			lazyEventModel = this.getLazyEventModel();
		} catch (Exception e) {
			FacesUtil.addActionListenerException(e, log);
		}
	}

	public void setLazyEventModel(ScheduleModel lazyEventModel) {
		this.lazyEventModel = lazyEventModel;
	}

	public ScheduleEvent getsEvent() {
		return sEvent;
	}

	public void setsEvent(ScheduleEvent sEvent) {
		this.sEvent = sEvent;
	}

	public UserEvent getuEvent() {
		if (sEvent != null) {
			uEvent = (UserEvent) sEvent.getData();
		}
		return uEvent;
	}

	public void setuEvent(UserEvent uEvent) {
		this.uEvent = uEvent;
	}

	public int getEventAmount() {
		eventAmount = ((BigInteger) patientService.findSingleByNamedQuery("UserEvent.findUndoAmount",
				new Object[] { FacesUtil.getUserFromSession().getId() })).intValue();
		return eventAmount;
	}

	public void setEventAmount(int eventAmount) {
		this.eventAmount = eventAmount;
	}

	public EvokPatientService getPatientService() {
		return patientService;
	}

	public void setPatientService(EvokPatientService patientService) {
		this.patientService = patientService;
	}

	public DoctorSchedule getDoctorSchedule() {
		if (FacesUtil.isKeyNull(doctorSchedule.getStatus())) {
			doctorSchedule.setStatus(EvokConstants.DOC_RESERVATION_STATUS_NORMAL);
		}
		return doctorSchedule;
	}

	public void setDoctorSchedule(DoctorSchedule doctorSchedule) {
		this.doctorSchedule = doctorSchedule;
	}

	public String getHeader() {
		if(EvokConstants.CALENDAR_TYPE_PATIENT == calendarType.intValue()){
			header = FacesUtil.getMessage("patient_reservations");
		}else{
			header = FacesUtil.getMessage("oa_task");
		}
		return header;
	}

	public void setHeader(String header) {
		this.header = header;
	}

	@SuppressWarnings("unchecked")
	public List<String> completeQueryName(String query) {
		return (List<String>) patientService.findByNamedQuery(Patient.QY_FINDNAME, new Object[] { query + "%",
				getQyDomainId() });
	}

	public Object[] getTherapyObj() {
		return therapyObj;
	}

	public void setTherapyObj(Object[] therapyObj) {
		this.therapyObj = therapyObj;
	}

	public Integer getCalendarType() {
		return calendarType;
	}

	public void setCalendarType(Integer calendarType) {
		this.calendarType = calendarType;
	}

	public List<Object[]> getTodoList() {
		if(todoList == null){
			todoList = patientService.getPatientTodoList(this.getSessionUser().getId());
		}
		return todoList;
	}

	public void setTodoList(List<Object[]> todoList) {
		this.todoList = todoList;
	}
	
	
}
